home *** CD-ROM | disk | FTP | other *** search
/ NOVA - For the NeXT Workstation / NOVA - For the NeXT Workstation.iso / SourceCode / AdobeExamples / NX_Patterns / Pattern.m < prev    next >
Text File  |  1992-12-19  |  10KB  |  403 lines

  1.  
  2. /*
  3.  * (a)  (C) 1990 by Adobe Systems Incorporated. All rights reserved.
  4.  *
  5.  * (b)  If this Sample Code is distributed as part of the Display PostScript
  6.  *    System Software Development Kit from Adobe Systems Incorporated,
  7.  *    then this copy is designated as Development Software and its use is
  8.  *    subject to the terms of the License Agreement attached to such Kit.
  9.  *
  10.  * (c)  If this Sample Code is distributed independently, then the following
  11.  *    terms apply:
  12.  *
  13.  * (d)  This file may be freely copied and redistributed as long as:
  14.  *    1) Parts (a), (d), (e) and (f) continue to be included in the file,
  15.  *    2) If the file has been modified in any way, a notice of such
  16.  *      modification is conspicuously indicated.
  17.  *
  18.  * (e)  PostScript, Display PostScript, and Adobe are registered trademarks of
  19.  *    Adobe Systems Incorporated.
  20.  * 
  21.  * (f) THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO
  22.  *    CHANGE WITHOUT NOTICE, AND SHOULD NOT BE CONSTRUED
  23.  *    AS A COMMITMENT BY ADOBE SYSTEMS INCORPORATED.
  24.  *    ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY
  25.  *    OR LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO
  26.  *    WARRANTY OF ANY KIND (EXPRESS, IMPLIED OR STATUTORY)
  27.  *    WITH RESPECT TO THIS INFORMATION, AND EXPRESSLY
  28.  *    DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, 
  29.  *    FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT
  30.  *    OF THIRD PARTY RIGHTS.
  31.  */
  32.  
  33. /*
  34.  *    Pattern.m
  35.  *
  36.  *    This class provides objects that correspond to patterns. It is modeled after the 
  37.  *    Font class. It not a rigorous definition but is just a vehicle for demostrating the
  38.  *    PostScript aspects of handling patterns.
  39.  *
  40.  *    Version:    2.0
  41.  *    Author:    Ken Fromm
  42.  *    History:
  43.  *            03-07-91        Added this comment.
  44.  */
  45.  
  46. #import "Pattern.h"
  47. #import "PSWpatterns.h"
  48. #import "PSWpatternsdemo.h"
  49. #import "PSWsamples.h"
  50.  
  51. #import "PatternApp.h"
  52.  
  53. #import <appkit/Font.h>
  54. #import <appkit/Matrix.h>
  55. #import <appkit/Panel.h>
  56. #import <appkit/View.h>
  57. #import <appkit/nextstd.h>
  58.  
  59. #import <objc/hashtable.h>
  60. #import <dpsclient/wraps.h>
  61. #import <dpsclient/dpsclient.h>
  62.  
  63. @implementation Pattern : Object
  64.  
  65. + initialize
  66. {
  67.     PSWPatternDefs();
  68.     PSWPatternDemoDefs();
  69.  
  70.     PSWPatternOctagon();
  71.     PSWPatternCircleStar();
  72.     PSWPatternWeave();
  73.     PSWPatternBrick();
  74.  
  75.     return self;
  76. }
  77.  
  78. + newPattern:(const char *) patternName  size:(float) patternSize
  79. {
  80.     return [Pattern  newPattern:patternName  size:patternSize  matrix:NX_IDENTITYMATRIX];
  81. }
  82.  
  83. + newPattern:(const char *) patternName  size:(float) patternSize  matrix:(const float *) patternMatrix
  84. {
  85.     self = [super  new];
  86.  
  87.     name = NXCopyStringBuffer(patternName);
  88.     size = patternSize;
  89.     if (name && size)
  90.     {
  91.         if (patternMatrix == NX_IDENTITYMATRIX)
  92.             pFlags._matrixIsIdentity = YES;
  93.         else if (patternMatrix == NX_FLIPPEDMATRIX)
  94.             pFlags._matrixIsFlipped = YES;
  95.         else
  96.             matrix = (float *) patternMatrix;
  97.     }
  98.  
  99.     return self;
  100. }
  101.  
  102. - free
  103. {
  104.     [image  free];
  105.     PSundefineuserobject(patternNum);
  106.     PSundefineuserobject(patternImageNum);
  107.     
  108.     return [super  free];
  109. }
  110.  
  111. /*
  112. *    This method is only here to vary the number of pattern
  113. *    images in a cell in order to generate the different test cases.
  114. *    In a real implementation, one value would be chosen
  115. *    as the optimal number of images per cell and to use this
  116. *    value in the +new methods to define the pattern there. 
  117. *
  118. *    Twice the width and height plus an additional number is used
  119. *    for the window size. The first cell is drawn at the origin of the
  120. *    image window. In many cases, part of this cell will be drawn outside
  121. *    the window resulting in an imcomplete image. The second cell
  122. *    is drawn entirely within the window. It is that cell that is used for
  123. *    compositing. Two time the width and height provides the room for
  124. *    the second cell. The 2 adds a little spacing so that the image does
  125. *    not lie on the edge of the window boundary.
  126. *
  127. *    This type of manipulation is necessary because patterns
  128. *    are locked down to device space which in this case is window
  129. *    space.
  130. */    
  131. - definePatternRows:(int) rows  andCols:(int) cols
  132. {
  133.     volatile BOOL    ok = NO;
  134.  
  135.     int        available;
  136.  
  137.     float        r, g, b;
  138.  
  139.     float        aMatrix[6];
  140.  
  141.     float        *aMatrixPtr;
  142.  
  143.     NXRect    imageRect;
  144.  
  145.     if (name && size && rows && cols)
  146.     {
  147.         if (pFlags._matrixIsIdentity || pFlags._matrixIsFlipped || !matrix)
  148.         {
  149.             bzero(aMatrix, sizeof(aMatrix));
  150.             aMatrix[0] = size;
  151.             if (pFlags._matrixIsFlipped)
  152.                 aMatrix[3] = -size;
  153.             else
  154.                 aMatrix[3] = size;
  155.             aMatrixPtr = aMatrix;
  156.         }
  157.         else
  158.             aMatrixPtr = matrix;
  159.  
  160.         NX_DURING
  161.             PSWCheckPattern(name, &available);
  162.             if (available)
  163.             {
  164.                 /********************************************************/
  165.                 /*
  166.                 *    Only used to give the compositing image the current color.
  167.                 *    Unnecessary in a real implementation of patterns.
  168.                 */
  169.                 PScurrentrgbcolor(&r, &g, &b);
  170.  
  171.                 /*
  172.                 *    If locking to window, then forego the PatternViewDict.
  173.                 */
  174.                 PSWBeginPattern();
  175.                 PSWBeginPatternView();
  176.                     PSWExpandPattern(name, aMatrixPtr, rows, cols);
  177.                 PSend();
  178.                 PSend();
  179.                 patternNum = DPSDefineUserObject(0);
  180.  
  181.                 /********************************************************/
  182.                 /*
  183.                 *    This portion is used to get the image for compositing.
  184.                 *    The composite approach is not recommended for a
  185.                 *    real implementation and so this portion is unnecessary.
  186.                 */
  187.                 if (patternNum)
  188.                 {
  189.                     PSWBeginPattern();
  190.                     PSWSizeImage(patternNum, &cellRect.origin.x,
  191.                         &cellRect.origin.y, &cellRect.size.width,
  192.                         &cellRect.size.height);
  193.                     PSend();
  194.  
  195.                     imageRect = cellRect;
  196.                     imageRect.size.width = imageRect.size.width * 2 + 2;
  197.                     imageRect.size.height = imageRect.size.height * 2 + 2;
  198.                     image = [Panel  newContent:&imageRect
  199.                         style:NX_TITLEDSTYLE
  200.                         backing:NX_RETAINED
  201.                         buttonMask:NX_CLOSEBUTTONMASK
  202.                         defer:NO];
  203.                     [[image  contentView]  setFlipped:NO];
  204.  
  205.                     [[image  contentView]  lockFocus];
  206.                         PSsetrgbcolor(r, g, b);
  207.                         PSWBeginPattern();
  208.                             PSWMakeImage(patternNum);
  209.                         PSend();
  210.                         patternImageNum = DPSDefineUserObject(0);
  211.                     [[image  contentView]  unlockFocus];
  212.                 }
  213.                 /********************************************************/
  214.  
  215.                 ok = YES;
  216.             }
  217.         NX_HANDLER
  218.         NX_ENDHANDLER
  219.     }
  220.  
  221.     if (!ok)
  222.     {
  223.         if (!available)
  224.             NXRunAlertPanel("Pattern", "Pattern dictionary not available.", "OK", NULL, NULL);
  225.         else
  226.             NXRunAlertPanel("Pattern", "Error while defining pattern", "OK", NULL, NULL);
  227.  
  228.         return nil;
  229.     }
  230.  
  231.     return self;
  232. }
  233.  
  234. /*************************************************************/
  235. /*
  236. *    The next two methods - image and compositeTo::
  237. *    provide information and perform operations for
  238. *    demonstration purposes.
  239. */
  240. /*
  241. *    This method returns the window holding the image.
  242. *    It can be inserted into the window list to show how
  243. *    the image is cached.
  244. */
  245. - image
  246. {
  247.     return image;
  248. }
  249.  
  250. /*
  251. *    Composite the center of the pattern cell to the point
  252. *    (x, y) in the currently focused view.
  253. */
  254. - compositeTo:(NXCoord) x  :(NXCoord) y
  255. {
  256.     PSWCompositePattern(patternNum, patternImageNum, x, y);
  257.  
  258.     return self;
  259. }
  260. /*************************************************************/
  261.  
  262. - (BOOL) hasMatrix
  263. {
  264.     if (matrix)
  265.         return YES;
  266.  
  267.     return NO;
  268. }
  269.  
  270. - (const float *) matrix
  271. {
  272.     return matrix;
  273. }
  274.  
  275. - (const char *) name
  276. {
  277.     return name;
  278. }
  279.  
  280. - (int) patternNum
  281. {
  282.     return patternNum;
  283. }
  284.  
  285. - (float) pointSize
  286. {
  287.     return size;
  288. }
  289.  
  290. /*
  291.  *    Place the pattern dictionary on top of the dictionary stack.
  292.  *    The pattern dictionary contains redefinition of the drawing and
  293.  *    showing operators to emulate the pattern operators in Level 2.
  294.  *    This emulation turns patterns into fonts thereby taking advantage
  295.  *    of the font cache.
  296.  *
  297.  *    The DrawingStatus variable performs the same function as the
  298.  *    NXDrawingStatus variable except that the trigger is the
  299.  *    composite-font radio buttons in the drawing options panel and
  300.  *    not the actual drawing status.
  301.  */
  302. - set
  303. {
  304.     int        type, lock;
  305.  
  306.     /********************************************************/
  307.     /*    Demonstration program only.                                */
  308.     type = [[NXApp  typeMatrix]  selectedTag];
  309.     lock = [[NXApp  lockMatrix]  selectedTag];
  310.     /********************************************************/
  311.  
  312.     if (patternNum)
  313.     {
  314.         PSWBeginPattern();
  315.         PSWSetPattern(patternNum);
  316.  
  317.         /*
  318.         *    Only necessary if locking to view. The "lock == ..."
  319.         *    checks are only for the demostration program.
  320.         */
  321.         if (NXDrawingStatus == NX_DRAWING &&
  322.             (lock == LOCK_VIEW || lock == LOCK_VIEWSCALE))
  323.         {
  324.             PSWBeginPatternView();
  325.             if (lock == LOCK_VIEWSCALE)
  326.                 PSWBeginPatternViewScale();
  327.         }
  328.  
  329.         /********************************************************/
  330.         /*    Demonstration program only.                                */
  331.         if (type == TYPE_DRAW)
  332.         {
  333.             PSWBeginPatternDraw();
  334.         }
  335.         else if (patternImageNum && type == TYPE_COMP)
  336.         {
  337.             PSWBeginPatternImage();
  338.             PSWSetPatternImage(patternImageNum);
  339.         }
  340.         /********************************************************/
  341.  
  342.         /*
  343.         *    Place a copy of userdict on the stack
  344.         */
  345.         PSuserdict();
  346.         PSbegin();
  347.     }
  348.  
  349.     return self;
  350. }
  351.  
  352. /*
  353.  *    This method is necessary for emulation of the setpattern in Level 2.
  354.  *    If the font method for patterns is being used, then this method removes
  355.  *    the definitions that replace the regular drawing and showing operators.
  356.  */
  357. - unset
  358. {
  359.     int        type, lock;
  360.  
  361.     /********************************************************/
  362.     /*    Demonstration program only.                                */
  363.     type = [[NXApp  typeMatrix]  selectedTag];
  364.     lock = [[NXApp  lockMatrix]  selectedTag];
  365.     /********************************************************/
  366.  
  367.     if (patternNum)
  368.     {
  369.         PSend();                /* Userdict */
  370.  
  371.         /********************************************************/
  372.         /*    Demonstration program only.                                */
  373.         /*    PatternDrawDict or PatternImageDict */
  374.         if (type == TYPE_DRAW || (patternImageNum && type == TYPE_COMP))
  375.             PSend();
  376.         /********************************************************/
  377.         
  378.                     if (NXDrawingStatus == NX_DRAWING)
  379.         /*
  380.         *    If locking to view than pop the PatternViewDict off the
  381.         *    dictionary stack and the PatternViewScaleDict if it is
  382.         *    also on the stack. Once the locking type has been
  383.         *    decided, the "lock == ..." checks are not necessary.
  384.         *    Only the NXDrawingStatus check should remain.
  385.         */
  386.         if (NXDrawingStatus == NX_DRAWING &&
  387.             (lock == LOCK_VIEW || lock == LOCK_VIEWSCALE))
  388.         {
  389.             PSend();
  390.             if (lock == LOCK_VIEWSCALE)
  391.                 PSend();
  392.         }
  393.  
  394.  
  395.         PSWUnsetPattern();
  396.         PSend();                /* PatternDict */
  397.     }
  398.  
  399.     return self;
  400. }
  401.  
  402. @end
  403.